package com.wengen.mybatis.session;

import com.wengen.mybatis.config.Configuration;
import com.wengen.mybatis.config.MappedStatement;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import java.util.Properties;

/**
 * @Auther: 朱稳根
 * @Date: 2018/8/27 20:40
 * @Description:
 * 1.把配置文件加载到内存
 * 2.生成sqlsession
 */
public class SqlSessionFactory {
    private Configuration config = new Configuration();

    public SqlSessionFactory() {
        loadDbInfo();//加载db配置文件
        loadMappersInfo();//加载所有的mapper.xml
    }

    public static final String MAPPER_CONFIG_LOCATION = "mappers";
    public static final String DB_CONFIG_FILE = "db.properties";

    //加载数据库配置信息
    private void loadDbInfo() {
        InputStream dbIn = SqlSessionFactory.class.getClassLoader().getResourceAsStream(DB_CONFIG_FILE);
        Properties properties = new Properties();
        try {
            //读取配置信息写入到properties对象
            properties.load(dbIn);

        } catch (IOException e) {
            e.printStackTrace();
        }
        //讲配置文件信息写入到对象
        config.setJdbcDriver(properties.get("jdbc.driver").toString());
        config.setJdbcUrl(properties.get("jdbc.url").toString());
        config.setJdbcUsername(properties.get("jdbc.username").toString());
        config.setJdbcPassword(properties.get("jdbc.password").toString());

    }

    private void loadMappersInfo() {
        URL resource = null;
        resource = SqlSessionFactory.class.getClassLoader().getResource(MAPPER_CONFIG_LOCATION);
        File mappers = new File(resource.getFile());//获取指定文件夹信息
        if (mappers.isDirectory()) {
            File[] files = mappers.listFiles();
            //循环遍历文件夹下所有的mapper.xml，解析后，注册到config对象
            for (File file : files) {
                loadMapperInfo(file);
            }

        }

    }

    //加载指定Mapper.xml文件
    private void loadMapperInfo(File file){
        //创建SAXreader对象
        SAXReader reader = new SAXReader();
        //通过read方法读取一个文件转换成document对象
        Document document = null;
        try {
            document = reader.read(file);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        //获取元素根节点对象<mapper>
        Element node = document.getRootElement();
        //获取命名空间
        String namespace = node.attribute("namespace").getData().toString();
        //获取select子节点
        List<Element> selects = node.elements("select");
        //遍历select子节点，将信息记录到MappedStatement对象，并记录到configuration
        for (Element element : selects) {
            MappedStatement statement = new MappedStatement();
            String id = element.attribute("id").getData().toString();
            String resultType = element.attribute("resultType").getData().toString();
            String sql = element.getData().toString();
            String resouceId = namespace +"."+ id;
            statement.setNamespace(namespace);
            statement.setSourceId(resouceId);
            statement.setResultType(resultType);
            statement.setSql(sql);
            //注册到configuration对象
            config.getMapStatements().put(resouceId, statement);
        }
    }


    public SqlSession openSqlssion(){
        return new DefaultSqlSession(config);
    }
}
